package com.sf.business.appointment.service.impl;

import com.sf.business.appointment.domain.BusServiceItem;
import com.sf.business.appointment.mapper.BusServiceItemMapper;
import com.sf.business.appointment.service.IBusServiceItemService;
import com.sf.business.appointment.util.AssertArgumentsUtil;
import com.sf.business.appointment.vo.BusServiceItemAuditVO;
import com.sf.business.appointment.vo.BusServiceItemVO;
import com.sf.business.audit.domain.BusCarPackageInfo;
import com.sf.business.audit.mapper.BusCarPackageInfoMapper;
import com.sf.business.audit.vo.BusCarPackageAuditInfoVO;
import com.sf.business.process.domain.BusBpmnInfo;
import com.sf.business.process.mapper.BusBpmnInfoMapper;
import com.sf.common.core.domain.entity.SysUser;
import com.sf.common.utils.DateUtils;
import com.sf.common.utils.SecurityUtils;
import com.sf.system.mapper.SysUserMapper;
import com.sf.system.service.ISysConfigService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 服务项Service业务层处理
 * 
 * @author LH
 * @date 2025-03-16
 */
@Service
public class BusServiceItemServiceImpl implements IBusServiceItemService 
{
    @Autowired
    private BusServiceItemMapper busServiceItemMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private ISysConfigService sysConfigService;
    @Autowired
    private BusBpmnInfoMapper busBpmnInfoMapper;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private BusCarPackageInfoMapper busCarPackageInfoMapper;

    /**
     * 查询服务项
     * 
     * @param id 服务项主键
     * @return 服务项
     */
    @Override
    public BusServiceItem selectBusServiceItemById(Long id)
    {
        return busServiceItemMapper.selectBusServiceItemById(id);
    }

    /**
     * 查询服务项列表
     * 
     * @param busServiceItem 服务项
     * @return 服务项
     */
    @Override
    public List<BusServiceItem> selectBusServiceItemList(BusServiceItem busServiceItem)
    {
        return busServiceItemMapper.selectBusServiceItemList(busServiceItem);
    }

    /**
     * 新增服务项
     * 
     * @return 结果
     */
    @Override
    public int insertBusServiceItem(BusServiceItemVO vo)
    {
        AssertArgumentsUtil.assertArguments(vo);

        BusServiceItem busServiceItem = new BusServiceItem();
        BeanUtils.copyProperties(vo, busServiceItem);

        if (busServiceItem.getCarPackage() == BusServiceItem.CAR_PACKAGE_NO)
            busServiceItem.setAuditStatus(BusServiceItem.AUDIT_STATUS_NOT);
        else
            busServiceItem.setAuditStatus(BusServiceItem.AUDIT_STATUS_INITIALIZE);
        busServiceItem.setCreateTime(DateUtils.getNowDate());
        busServiceItem.setSaleStatus(BusServiceItem.SALE_STATUS_OFF); // 默认下架
        return busServiceItemMapper.insertBusServiceItem(busServiceItem);
    }

    /**
     * 修改服务项
     * 
     * @return 结果
     */
    @Override
    public int updateBusServiceItem(BusServiceItemVO vo)
    {
        AssertArgumentsUtil.assertArguments(vo);

        BusServiceItem busServiceItemFromDB = busServiceItemMapper.selectBusServiceItemById(vo.getId());
        if (busServiceItemFromDB == null)
            throw new IllegalArgumentException("数据不存在");
        if (busServiceItemFromDB.getAuditStatus() == BusServiceItem.AUDIT_STATUS_AUDITING)
            throw new IllegalArgumentException("数据不能修改 (审核中 ) ");
        if (busServiceItemFromDB.getSaleStatus() == BusServiceItem.SALE_STATUS_ON)
            throw new IllegalArgumentException("数据不能修改 (已上架 ) ");

        BusServiceItem busServiceItem = new BusServiceItem();
        BeanUtils.copyProperties(vo, busServiceItem);
        if (busServiceItemFromDB.getAuditStatus() == BusServiceItem.AUDIT_STATUS_AUDIT_PASS && vo.getCarPackage() == BusServiceItem.CAR_PACKAGE_YES)
            busServiceItem.setAuditStatus(BusServiceItem.AUDIT_STATUS_INITIALIZE);

        return busServiceItemMapper.updateBusServiceItem(busServiceItem);
    }

    /**
     * 批量删除服务项
     * 
     * @param ids 需要删除的服务项主键
     * @return 结果
     */
    @Override
    public int deleteBusServiceItemByIds(Long[] ids)
    {
        return busServiceItemMapper.deleteBusServiceItemByIds(ids);
    }

    /**
     * 删除服务项信息
     * 
     * @param id 服务项主键
     * @return 结果
     */
    @Override
    public int deleteBusServiceItemById(Long id)
    {
        return busServiceItemMapper.deleteBusServiceItemById(id);
    }

    @Override
    public int saleOnBusServiceItemByIds(Long id) {
        BusServiceItem busServiceItem = busServiceItemMapper.selectBusServiceItemById(id);

        if (busServiceItem == null)
            throw new IllegalArgumentException("数据不存在");
        if (busServiceItem.getSaleStatus() == BusServiceItem.SALE_STATUS_ON)
            throw new IllegalArgumentException("数据不能修改 (已上架 ) ");
        if (busServiceItem.getCarPackage() == BusServiceItem.CAR_PACKAGE_YES && busServiceItem.getAuditStatus() != BusServiceItem.AUDIT_STATUS_AUDIT_PASS)
            throw new IllegalArgumentException("数据不能修改 (套餐且没有审核通过, 不允许上架 ) ");

        busServiceItem.setSaleStatus(BusServiceItem.SALE_STATUS_ON);
        return busServiceItemMapper.updateBusServiceItem(busServiceItem);
    }

    @Override
    public int saleOffBusServiceItemByIds(Long id) {
        BusServiceItem busServiceItem = busServiceItemMapper.selectBusServiceItemById(id);

        if (busServiceItem == null)
            throw new IllegalArgumentException("数据不存在");
        if (busServiceItem.getSaleStatus() == BusServiceItem.SALE_STATUS_OFF)
            throw new IllegalArgumentException("数据不能修改 (已下架 ) ");

        busServiceItem.setSaleStatus(BusServiceItem.SALE_STATUS_OFF);
        return busServiceItemMapper.updateBusServiceItem(busServiceItem);
    }

    @Override
    public BusCarPackageAuditInfoVO getAuditData(Long id) {
        // 1. 查询服务项 数据
        BusServiceItem busServiceItem = busServiceItemMapper.selectBusServiceItemById(id);
        Assert.notNull(busServiceItem, "服务项 数据不存在");
        if (busServiceItem.getAuditStatus() != BusServiceItem.AUDIT_STATUS_INITIALIZE && busServiceItem.getAuditStatus() != BusServiceItem.AUDIT_STATUS_READJUST)
            throw new IllegalArgumentException("服务项 数据状态不正确, 需要 [ 初始化0 / 重新调整 3]");

        // 创建最终要返回的数据
        BusCarPackageAuditInfoVO info = new BusCarPackageAuditInfoVO();
        info.setServiceItem(busServiceItem);

        // 获取店长并放入 (sys_role, sys_user, sys_user_role)
        List<SysUser> shopOwners = sysUserMapper.selectUserByRoleKey("shopowner");
        if (shopOwners != null && shopOwners.size() > 0 )
            info.setShopOwners(shopOwners);

        // 获取参数设置中的 套餐限制条件
        BigDecimal discountPriceLimit = new BigDecimal(sysConfigService.selectConfigByKey("discountPriceLimit"));
        info.setDiscountPrice(discountPriceLimit);

        // 拿服务项的折扣金额和限制条件进行比较 (折扣价大于限制, 加入财务)
        if (busServiceItem.getDiscountPrice().compareTo(discountPriceLimit) > 0) {
            List<SysUser> financial = sysUserMapper.selectUserByRoleKey("financial");
            info.setFinances(financial);
        }

        return info;
    }

    @Override
    @Transactional
    public void audit(BusServiceItemAuditVO vo) {
        // 1. 数据非空校验
        Assert.notNull(vo.getId(), "参数缺失, 服务项主键 id");
        Assert.notNull(vo.getShopOwnerId(), "参数缺失, 店长人员主键 shopOwnerId");
        // 2. 查询 bus_service_item 表数据 by id, 并非空校验
        BusServiceItem busServiceItem = busServiceItemMapper.selectBusServiceItemById(vo.getId());
        Assert.notNull(busServiceItem, "数据不存在");
        // 3. 判断当前服务项状态是否为 [初始化 / 重新调整], 不是就抛异常
        if (!busServiceItem.getAuditStatus().equals(BusServiceItem.AUDIT_STATUS_INITIALIZE) && !busServiceItem.getAuditStatus().equals(BusServiceItem.AUDIT_STATUS_READJUST) )
            throw new IllegalArgumentException("数据状态不正确, 需要 [ 初始化0 / 重新调整 3]");
        // 4. 查询出最新部署的服务项套餐审核 bpmnInfo 信息 (根据版本号降序限制1)
        BusBpmnInfo busBpmnInfo = busBpmnInfoMapper.selectBpmnInfoLastVersion();
        Assert.notNull(busBpmnInfo, "套餐审核流程信息不存在");

        // 5. 设置流程变量
        Map<String, Object> map = new HashMap<>();
        map.put("disCountPrice", busServiceItem.getDiscountPrice().longValue());    // activiti 不支持 BigDecimal 类型, 转为 long
        map.put("shopOwnerId", vo.getShopOwnerId());
        // 获取限制条件 (在 config 中), 以判定是否需要财务负责人插手审批
        String discountPriceLimit = sysConfigService.selectConfigByKey("discountPriceLimit");
        // 折扣金额 大于限制条件, 才加入财务人员审核
        if (busServiceItem.getDiscountPrice().compareTo(new BigDecimal(discountPriceLimit)) >= 0) {
            Assert.notNull(vo.getFinanceId(), "参数缺失, 财务人员主键 financeId");
            // 设置财务负责人
            map.put("financeId", vo.getFinanceId());
        }
        // 6. 创建 CarPackageAudit 对象, 设置数据 (服务项默认状态审核中), 保存到数据库中
        BusCarPackageInfo busCarPackageInfo = new BusCarPackageInfo();
        busCarPackageInfo.setCreatorId(SecurityUtils.getUserId().toString());
        busCarPackageInfo.setInfo(vo.getInfo());
        busCarPackageInfo.setServiceItemId(busServiceItem.getId());
        busCarPackageInfo.setServiceItemInfo(busServiceItem.getInfo());
        busCarPackageInfo.setServiceItemName(busServiceItem.getName());
        busCarPackageInfo.setServiceItemPrice(busServiceItem.getDiscountPrice());
        busCarPackageInfo.setCreateTime(new Date());
        busCarPackageInfo.setStatus(BusCarPackageInfo.STATUS_AUDITING);
        busCarPackageInfoMapper.insertBusCarPackageInfo(busCarPackageInfo); // 数据没封装完, 但是需要插入到数据库中, 获取到 id

        // 7. activiti 启动流程
        ProcessInstance instance = runtimeService.startProcessInstanceByKey(
                busBpmnInfo.getProcessDefinitionKey(),
                busCarPackageInfo.getId().toString(),       // businessKey : 使用 bus_car_package_audit 表的 id
                map);

        // 8. 设置 流程实例的 id
        busCarPackageInfo.setInstanceId(instance.getId());
        busCarPackageInfoMapper.updateBusCarPackageInfo(busCarPackageInfo); // 数据填充完毕

        // 9. 更新服务项状态为 [审核中]
        busServiceItem.setAuditStatus(BusServiceItem.AUDIT_STATUS_AUDITING);
        busServiceItemMapper.updateBusServiceItem(busServiceItem);
    }
}
